﻿using System;
using System.Collections.Generic;
using System.Text;
using Placid.Core;

namespace Placid.PivotSourceImpl
{
    public class PivotSourceRow : IPivotSourceRow, IEnumerable<IPivotSourceCell>
    {
        private int _index;
        private int _sourceIndex;
        private List<PivotSourceCell> _cells;
        private Dictionary<int, PivotSourceCell> _cellsByIndex;
        private Dictionary<string, PivotSourceCell> _cellsByCoumnName;
        private Dictionary<PivotSourceColumn, PivotSourceCell> _cellsByCoumn;
        private PivotSource _container;

        internal protected PivotSourceRow(PivotSource container, int index, int sourceIndex)
        {
            if(container != null) {
                _container = container;
            } else throw new Exception("IPvSource Container is a null reference.");

            _index = index;
            _sourceIndex = sourceIndex;

            _cells = new List<PivotSourceCell>();
            _cellsByIndex = new Dictionary<int, PivotSourceCell>();
            _cellsByCoumnName = new Dictionary<string, PivotSourceCell>();
            _cellsByCoumn = new Dictionary<PivotSourceColumn, PivotSourceCell>();

            BuildCells();
        }

        private void BuildCells()
        {
            PivotSourceColumn col;
            PivotSourceCell cell;

            _cells.Clear();
            _cellsByIndex.Clear();
            _cellsByCoumnName.Clear();
            _cellsByCoumn.Clear();

            for(int colIndex =0; colIndex < _container.Columns.Count; colIndex++) {
                col = _container.Columns[colIndex];
                cell = new PivotSourceCell(_container._source.Rows[_sourceIndex][col.SourceIndex]);
                _cellsByIndex.Add(colIndex, cell);
                _cellsByCoumn.Add(col, cell);
                _cellsByCoumnName.Add(col.Name, cell);
                _cells.Add(cell);
            }
        }

        public IPivotSourceCell this[int index]
        {
            get
            {
                if(_cellsByIndex != null && _cellsByIndex.ContainsKey(index))
                    return _cellsByIndex[index];
                else throw new Exception("Index " + index.ToString() + " not found.");
            }
        }

        public IPivotSourceCell this[string name]
        {
            get
            {
                if(_cellsByCoumnName != null && _cellsByCoumnName.ContainsKey(name))
                    return _cellsByCoumnName[name];
                else throw new Exception("Column '" + name + "' not found.");
            }
        }

        public IPivotSourceCell this[PivotSourceColumn column]
        {
            get
            {
                if(column != null) {
                    if(_cellsByCoumn != null && _cellsByCoumn.ContainsKey(column))
                        return _cellsByCoumn[column];
                    else throw new Exception("column '" + column.Name + "' not found.");
                } else {
                    throw new Exception("column is a null reference.");
                }
            }
        }

        public PivotSource PvSource
        {
            get { return _container; }
        }

        internal protected int SourceIndex
        {
            get
            {
                return _sourceIndex;
            }
        }

        #region IPvSourceRow Members

        public int Index
        {
            get { return _index; }
        }

        public List<IPivotSourceCell> Cells
        {
            get { return _cells.ConvertAll<IPivotSourceCell>(new Converter<PivotSourceCell, IPivotSourceCell>(delegate(PivotSourceCell c) { return (IPivotSourceCell)c; })); }
        }

        public IPivotSource Container
        {
            get { return _container; }
        }

        public IPivotSourceCell GetCell(int columnIndex)
        {
            return this[columnIndex];
        }

        public IPivotSourceCell GetCell(string columnName)
        {
            return this[columnName];
        }

        #endregion

        public override string ToString()
        {
            string str = "";

            foreach(IPivotSourceCell cell in this) {
                str += cell.ToString() + " | ";
            }
            if(str != "") str = str.Substring(0, str.Length - 2);
            return str;
        }

        #region IEnumerable<IPvSourceCell> Members

        public IEnumerator<IPivotSourceCell> GetEnumerator()
        {
            return Cells.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _cells.GetEnumerator();
        }

        #endregion
    }
}
